package com.kcht.rfid.rd30.secretary.dispatch.impl.operation;

import com.google.protobuf.InvalidProtocolBufferException;
import com.kcht.rfid.rd30.secretary.core.command.ReadCommand;
import com.kcht.rfid.rd30.secretary.core.command.BasicReaderCommand;
import com.kcht.rfid.rd30.secretary.core.common.ReaderResponseStatus;
import com.kcht.rfid.rd30.secretary.core.response.ReadResponse;
import com.kcht.rfid.rd30.secretary.dispatch.IReaderChannel;
import lombok.extern.slf4j.Slf4j;
import uhf_msg.Uhf;

import java.time.LocalDateTime;
import java.util.Observer;
import java.util.Set;

/**
 * 读取操作
 */
@Slf4j
public class Read extends BaseOperation {

    public Read(Observer observer) {
        super(observer);
    }

    @Override
    protected void handlerOperation(IReaderChannel channel, Uhf.uhf_response response, Integer antId, BasicReaderCommand command) {
        String[] resList = response.getEpcInventRes().toString().split(" ");
        String epc = resList[resList.length - 1];
        epc = epc.substring(1, epc.length() - 2);
        ReadCommand readCommand = (ReadCommand) command;
        Set<String> allowedEpcS = readCommand.getAllowedEpcS();
        if(allowedEpcS==null||allowedEpcS.contains(epc)){
            Uhf.uhf_request request = readRequest(readCommand);
            ReadResponse reply = new ReadResponse();
            reply.setEpc(epc);
            reply.setBank(readCommand.getBank());
            reply.setLength(readCommand.getLength());
            reply.setOffset(readCommand.getOffset());
            reply.setAntId(antId);
            reply.setIp(channel.getIp());
            byte[] recv = channel.sendRecv(request.toByteArray());
            if (recv != null) {
                Uhf.uhf_response readResponse = null;
                try {
                    readResponse = Uhf.uhf_response.parseFrom(recv);
                } catch (InvalidProtocolBufferException e) {
                    throw new RuntimeException("protoc不正确");
                }
                int readStatus = readResponse.getStatus();
                if (readStatus == 0) {
                    String result = readResponse.getEpcReadRes().toString().split("\n")[2].split(" ")[1];
                    result = result.substring(1, result.length() - 1);
                    log.info("读取标签成功--->ip:{},天线接口:{},epc:{},data:{}", channel.getIp(), antId, epc, result);
                    reply.setDateTime(LocalDateTime.now());
                    reply.setStatus(ReaderResponseStatus.成功);
                    reply.setValue(result);
                } else if (readStatus == 1) {
                    reply.setDateTime(LocalDateTime.now());
                    if (readResponse.getEpcReadRes().getErrCode() == 524353) {
                        log.error("读取标签失败,密码错误--->ip:{},天线接口:{},epc:{},密码:{}", channel.getIp(), antId, epc, command.getPwd());
                        reply.setStatus(ReaderResponseStatus.密码错误);
                    } else {
                        log.info("读取标签失败,其他错误--->ip:{},天线接口:{},epc:{},返回状态:1", channel.getIp(), antId, epc);
                        reply.setStatus(ReaderResponseStatus.失败);
                    }
                }
            } else {
                log.info("读取标签失败,接收响应超时--->ip:{},天线接口:{},epc:{}", channel.getIp(), antId, epc);
                reply.setDateTime(LocalDateTime.now());
                reply.setStatus(ReaderResponseStatus.响应超时);
            }
            super.response(reply);
        }
    }


    private Uhf.uhf_request readRequest(ReadCommand command) {
        Uhf.uhf_request request = Uhf.uhf_request.getDefaultInstance();
        Uhf.uhf_request.Builder builder = request.toBuilder()
                .setType(Uhf.uhf_request.HeadType.epcRead)
                .setRead(Uhf.uhf_request.ReadPara.newBuilder()
                        .setMb(command.getBank().ordinal())
                        .setPointer(command.getOffset())
                        .setCount(command.getLength())
                        .build());
        if (!"无".equals(command.getPwd())) {
            builder.setEpcAccess(uhf_msg.Uhf.uhf_request.EpcAccessPara.newBuilder()
                    .setPwdH(command.getHighPwd())
                    .setPwdL(command.getLowPwd())
                    .build());
        }
        request = builder.build();
        return request;
    }
}
